package co.unal.visor.view;

import java.awt.ScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JSlider;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import co.unal.visor.util.BitWise;
import co.unal.visor.util.HistoGram;

import co.unal.visor.util.RGB;
import co.unal.visor.view.*;
import co.unal.visor.controller.FilterManager;
import co.unal.visor.model.*;
import co.unal.visor.model.interfaces.ISink;

import filter.Transformation2D;

public class Viewer extends JFrame {

	private static final long serialVersionUID = 1L;
	private JMenu jMenuArchivo;

	private JMenuBar jMenuBar1;
	private JMenu jMenuAyuda;
	private JMenu jMenuFiltros;
	private JMenuItem jMenuItemAbrirArchivo;
	private JMenuItem jMenuItemHistograma;
	private JMenuItem jMenuItemBlancoNegro;
	private String apuntar_a_este_directorio = "pruebasBMP/";
	private JFileChooser fc = new JFileChooser(apuntar_a_este_directorio);

	JFrame Rotacion;
	Image imagen;
	Lienzo lienzo;
	ScrollPane panelLienzo;
	FilterManager fm;
	File filename;
	int grado_rot = 0;

	public void customInitComponents() {
		// configura el LookAndFeel al del sistema operativo
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		jMenuBar1 = new JMenuBar();
		jMenuArchivo = new JMenu();
		jMenuFiltros = new JMenu();
		jMenuAyuda = new JMenu();
		jMenuItemAbrirArchivo = new JMenuItem();
		jMenuItemHistograma = new JMenuItem();
		jMenuItemBlancoNegro = new JMenuItem();

		this.setSize(640, 480);

		Rotacion = new javax.swing.JFrame();
		this.addMouseListener(new MouseListener() {

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub

				setRotationWindow();
				setSize((int) Math.sqrt(Math.pow(imagen.getHeight(), 2)
						+ Math.pow(imagen.getWidth(), 2)) + 8,
						(int) Math.sqrt(Math.pow(imagen.getHeight(), 2)
								+ Math.pow(imagen.getWidth(), 2)) + 60);
				updateLienzo();
			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub

			}
		});

		jMenuArchivo.setText("Archivo");
		jMenuAyuda.setText("Ayuda");
		jMenuFiltros.setText("Filtros");

		jMenuItemAbrirArchivo.setText("Abrir imagen");
		jMenuItemBlancoNegro.setText("Blanco y Negro");
		jMenuItemHistograma.setText("Histograma");

		jMenuItemAbrirArchivo
				.addActionListener(new java.awt.event.ActionListener() {

					public void actionPerformed(java.awt.event.ActionEvent evt) {
						jMenuItemArchivoActionPerformed(evt);
					}
				});

		jMenuItemHistograma
				.addActionListener(new java.awt.event.ActionListener() {

					public void actionPerformed(java.awt.event.ActionEvent evt) {
						try {
							jMenuItemHistogramaActionPerformed(evt);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});

		jMenuItemBlancoNegro
				.addActionListener(new java.awt.event.ActionListener() {

					public void actionPerformed(java.awt.event.ActionEvent evt) {
						try {
							jMenuItemBlancoNegroActionPerformed(evt);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});

		jMenuAyuda.getPopupMenu();
		JPopupMenu.setDefaultLightWeightPopupEnabled(false);
		jMenuArchivo.getPopupMenu();
		JPopupMenu.setDefaultLightWeightPopupEnabled(false);

		jMenuBar1.add(jMenuArchivo);
		jMenuBar1.add(jMenuFiltros);
		jMenuBar1.add(jMenuAyuda);

		jMenuArchivo.add(jMenuItemAbrirArchivo);
		jMenuFiltros.add(jMenuItemBlancoNegro);
		jMenuAyuda.add(jMenuItemHistograma);
		setJMenuBar(jMenuBar1);

		// crea buff strategy par optimizar dibujado
		this.createBufferStrategy(2);

	}

	/** Creates new form Visor */
	public Viewer() {
		// initComponents();
		this.setVisible(true);
		// this.setIconImage(new
		// ImageIcon(getClass().getClassLoader().getResource("icon.ico")).getImage());
		fm = new FilterManager();
		customInitComponents();
	}

	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				new Viewer().setVisible(true);
			}
		});
	}

	public void updateLienzo() {
		// retira la imagen previamente abierta
		if (lienzo != null) {
			this.remove(panelLienzo);
		}
		lienzo = new Lienzo(this);

		panelLienzo = new ScrollPane();
		panelLienzo.add(lienzo);

		this.getContentPane().add(panelLienzo);
		this.pack();

		// Procesar imagen usando filtros

		if (imagen != null) {

			if (imagen.getStripArray() != null) {

				lienzo.setPMatrixFromImage(imagen);
				setSize((int) imagen.getWidth(), (int) imagen.getHeight() + 50);

			} else {

				System.out.println("No se pudo mostrar la imagen: imagen nula");

			}
		}

	}

	public void jMenuItemBlancoNegroActionPerformed(ActionEvent evt) {
		//fm.register(new GreyscaleFilter());
		//this.imagen = fm.execute();
		GreyscaleFilter blancoNegro = new GreyscaleFilter();
		blancoNegro.process(imagen);
		
		updateLienzo();
	}

	public void jMenuItemHistogramaActionPerformed(
			java.awt.event.ActionEvent evt) {

		// fm.register(new HistoGram());
		// this.imagen = fm.execute();
		new VisualizarHistograma(imagen);

	}

	private void jMenuItemArchivoActionPerformed(java.awt.event.ActionEvent evt) {
		// configura los filtros de archivo correspondientes
		/*
		 * ExtensionFilter filter=new ExtensionFilter();
		 * fc.setFileFilter(filter);
		 */
		ImageSource ireader;

		if (fc == null) {
			fc = new JFileChooser();
			fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		}
		int returnVal = fc.showOpenDialog(this);
		try {
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File filename = fc.getSelectedFile();
				fc.setCurrentDirectory(filename);

				if (filename != null) {
					ireader = new ImageSource(filename.getPath());
					this.imagen = ireader.getImage();
					System.out.println("ruta: " + filename.getPath());
					updateLienzo();

					if (imagen != null) {
						if (imagen.getStripArray() != null) {
							lienzo.setPMatrixFromImage(imagen);
							setSize((int) imagen.getWidth(),
									(int) imagen.getHeight() + 50);
						} else {
							System.out
									.println("No se pudo mostrar la imagen: imagen nula");
						}
					}
				}
			}
		} catch (IOException ex) {
			Logger.getLogger(Viewer.class.getName())
					.log(Level.SEVERE, null, ex);
		}
	}

	public void setRotationWindow() {
		grado_rot = grado_rot + 5;
		System.out.println("gradorotation=" + grado_rot);
		Transformation2D.rotateCenteredImage(imagen, grado_rot, lienzo);
		updateLienzo();
		lienzo.repaint();

	}

}
